using MediatR;
using Microsoft.EntityFrameworkCore;
using RBAC.Domain.SmartHealthcare;
using RBAC.Domain.SmartHealthcare.Hosiptial;
using RBAC.ErrorCode;
using RBAC.Interstructrue;
using SmartHealthcare.Read.Api.Application.Command.PatientList;
using SmartHealthcare.Read.Api.DTo;

namespace SmartHealthcare.Read.Api.Application.Handler.PatientList
{
    /// <summary>
    /// 获取患者住院登记信息处理器
    /// </summary>
    public class GetPatientRegistryHandler : IRequestHandler<GetPatientRegistryCommand, APIResult<List<PatientRegistryDto>>>
    {
        private readonly RBACDbContext _dbContext;
        private readonly ILogger<GetPatientRegistryHandler> _logger;

        public GetPatientRegistryHandler(RBACDbContext dbContext, ILogger<GetPatientRegistryHandler> logger)
        {
            _dbContext = dbContext;
            _logger = logger;
        }

        /// <summary>
        /// 获取患者住院登记信息
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task<APIResult<List<PatientRegistryDto>>> Handle(GetPatientRegistryCommand request, CancellationToken cancellationToken)
        {
            var result = new APIResult<List<PatientRegistryDto>>();

            try
            {
                // 检查是否有查询参数
                if (!request.HasAnyParameter())
                {
                    _logger.LogInformation("未提供查询参数，将查询所有患者住院登记信息");
                }
                else
                {
                    // 验证时间范围
                    if (!request.IsTimeRangeValid())
                    {
                        result.Code = APIEnums.Fail;
                        result.Msg = "开始时间不能大于结束时间";
                        return result;
                    }

                    _logger.LogInformation($"开始查询患者住院登记信息，病人卡号：{request.MedicalCard}，病人姓名：{request.PatientName}，时间范围：{request.StartTime} - {request.EndTime}");
                }

                // 构建查询
                var query = from registry in _dbContext.inpatientRegistries
                           join patient in _dbContext.patientLists on registry.MedicalCard equals patient.MedicalCard
                           join department in _dbContext.Departments on registry.DepartmentId equals department.Id
                           join room in _dbContext.hospitalRooms on registry.WardNo equals room.Id
                           join bed in _dbContext.HospitalBeds on registry.WardId equals bed.Id
                           where registry.IsDeleted == false
                             && patient.IsDeleted == false
                             && department.IsDeleted == false
                             && room.IsDeleted == false
                             && bed.IsDeleted == false
                           select new
                           {
                               registry.Id, // 住院登记ID
                               registry.MedicalCard,
                               registry.DepartmentId,
                               registry.WardNo,
                               registry.WardId,
                               registry.AdvancePayment,
                               registry.DiseaseDescription,
                               registry.DrugContraindications,
                               registry.AdmissionTime,
                               registry.Discharge_status,
                               registry.CreateTime,
                               patient.Name,
                               department.DepartmentName,
                               room.HospitalRoomCode,
                               bed.HospitalBedId
                           };

                // 根据参数筛选
                if (!string.IsNullOrWhiteSpace(request.MedicalCard))
                {
                    query = query.Where(x => x.MedicalCard.Contains(request.MedicalCard));
                    _logger.LogInformation($"按病人卡号筛选：{request.MedicalCard}");
                }

                if (!string.IsNullOrWhiteSpace(request.PatientName))
                {
                    query = query.Where(x => x.Name.Contains(request.PatientName));
                    _logger.LogInformation($"按病人姓名筛选：{request.PatientName}");
                }

                if (request.StartTime.HasValue)
                {
                    query = query.Where(x => x.AdmissionTime >= request.StartTime.Value);
                    _logger.LogInformation($"按开始时间筛选：{request.StartTime.Value}");
                }

                if (request.EndTime.HasValue)
                {
                    query = query.Where(x => x.AdmissionTime <= request.EndTime.Value);
                    _logger.LogInformation($"按结束时间筛选：{request.EndTime.Value}");
                }

                var patientRegistries = await query.ToListAsync(cancellationToken);

                var resultList = patientRegistries.Select(info => new PatientRegistryDto
                {
                    InpatientRegistryId = info.Id, // 住院登记ID
                    MedicalCard = info.MedicalCard,
                    PatientName = info.Name,
                    DepartmentId = info.DepartmentId,
                    DepartmentName = info.DepartmentName,
                    HospitalRoomCode = info.HospitalRoomCode,
                    HospitalBedId = info.HospitalBedId,
                    AdvancePayment = info.AdvancePayment,
                    DiseaseDescription = info.DiseaseDescription ?? string.Empty,
                    DrugContraindications = info.DrugContraindications ?? string.Empty,
                    AdmissionTime = info.AdmissionTime,
                    DischargeStatus = info.Discharge_status,
                    CreateTime = info.CreateTime
                }).ToList();

                result.Data = resultList;
                result.Code = APIEnums.Success;
                result.Msg = $"查询成功，共找到{resultList.Count}条记录";

                _logger.LogInformation($"查询患者住院登记信息成功，共找到{resultList.Count}条记录");
            }
            catch (Exception ex)
            {
                result.Code = APIEnums.Fail;
                result.Msg = "查询患者住院登记信息失败";
                _logger.LogError(ex, "查询患者住院登记信息时发生异常");
            }

            return result;
        }
    }
} 